home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / manageme / tcpdump-.7 / tcpdump- / tcpdump-richard-1.7 / libpcap-0.0 / savefile.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-19  |  4.8 KB  |  186 lines

  1. /*
  2.  * Copyright (c) 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21. #ifndef lint
  22. static char rcsid[] =
  23.     "@(#)$Header: savefile.c,v 1.16 94/06/20 19:07:56 leres Exp $ (LBL)";
  24. #endif
  25.  
  26. /*
  27.  * savefile.c - supports offline use of tcpdump
  28.  *    Extraction/creation by Jeffrey Mogul, DECWRL
  29.  *    Modified by Steve McCanne, LBL.
  30.  *
  31.  * Used to save the received packet headers, after filtering, to
  32.  * a file.
  33.  * The first record in the file contains saved values for the machine
  34.  * dependent values so we can print the dump file on any architecture.
  35.  */
  36.  
  37. #include <sys/types.h>
  38. #include <sys/time.h>
  39.  
  40. #include <errno.h>
  41. #include <memory.h>
  42. #include <stdio.h>
  43. #if __STDC__
  44. #include <stdlib.h>
  45. #endif
  46. #include <unistd.h>
  47.  
  48. #include "pcap-int.h"
  49. #include "order.h"
  50.  
  51.  
  52. static int sf_write_header(pcap_dumper_t *p, int linktype, int thiszone, int snaplen);
  53.  
  54. /*
  55.  * Initialize so that sf_write() will output to the file named 'fname'.
  56.  */
  57. pcap_dumper_t *
  58. pcap_dump_open(pcap_t *p, char *fname, int format)
  59. {
  60.     pcap_dumper_t *dumper;
  61.     FILE *f;
  62.  
  63.     if ((dumper = malloc(sizeof(*dumper))) == NULL)
  64.         return NULL;
  65.     if (fname[0] == '-' && fname[1] == '\0')
  66.         f = stdout;
  67.     else {
  68.         f = fopen(fname, "w");
  69.         if (f == NULL) {
  70.             sprintf(p->errbuf, "%s: %s",
  71.                 fname, pcap_strerror(errno));
  72.             free(dumper);
  73.             return NULL;
  74.         }
  75.     }
  76.     dumper->wfile = f;
  77.     dumper->format = format;
  78.     dumper->swapped = 0;
  79.     if (format == FORMAT_SNOOP2 && byteorder() != BIG_ENDIAN)
  80.         dumper->swapped = 1;
  81.  
  82.     (void)sf_write_header(dumper, p->linktype, p->tzoff, p->snapshot);
  83.  
  84.     return dumper;
  85. }
  86.  
  87. /*
  88.  * Output a packet to the initialized dump file.
  89.  */
  90. void
  91. pcap_dump(u_char *d, const struct pcap_hdr *h, const u_char *sp)
  92. {
  93.     pcap_dumper_t *p = (pcap_dumper_t *)d;
  94.     FILE * f = p->wfile;
  95.     struct pcap_pkthdr tcpdump;
  96.     struct pcap_snoop_pkthdr snoop;
  97.     int align = 0;
  98.  
  99.     switch (p->format) {
  100.     case FORMAT_TCPDUMP:
  101.         tcpdump.ts = h->ts;
  102.         tcpdump.caplen = h->caplen;
  103.         tcpdump.len = h->len;
  104.         (void)fwrite((char *)&tcpdump, sizeof(tcpdump), 1, f);
  105.         (void)fwrite((char *)sp, h->caplen, 1, f);
  106.         break;
  107.     case FORMAT_SNOOP2:
  108.         /* there is a compensation here for old versions of snoop that 
  109.             can't handle dump files that are not 32-bit aligned */
  110.         snoop.len = h->len;
  111.         snoop.caplen = h->caplen;
  112.         snoop.totlen = sizeof(snoop)+h->caplen;
  113. #ifndef NO_SNOOP_ALIGN
  114.         if ((align = 4 - (snoop.totlen % 4)) == 4)
  115.             align = 0;
  116.         else
  117.             snoop.totlen += align;
  118. #endif
  119.         snoop.drops = h->drops;
  120.         snoop.secs = h->ts.tv_sec;
  121.         snoop.usecs = h->ts.tv_usec;
  122.         if (p->swapped) {
  123.             snoop.len = SWAPLONG(snoop.len);
  124.             snoop.caplen = SWAPLONG(snoop.caplen);
  125.             snoop.totlen = SWAPLONG(snoop.totlen);
  126.             snoop.drops = SWAPLONG(snoop.drops);
  127.             snoop.secs = SWAPLONG(snoop.secs);
  128.             snoop.usecs = SWAPLONG(snoop.usecs);
  129.         }
  130.         (void)fwrite((char *)&snoop, sizeof(snoop), 1, f);
  131.         (void)fwrite((char *)sp, h->caplen, 1, f);
  132. #ifndef NO_SNOOP_ALIGN
  133.         if (align)
  134.             (void)fseek(f, align, SEEK_CUR);
  135. #endif
  136.         break;
  137.     }
  138. }
  139.  
  140. void
  141. pcap_dump_close(pcap_dumper_t *p)
  142. {
  143.     FILE *f = p->wfile;
  144.  
  145.     if (f != stdout)
  146.         fclose(f);
  147. }
  148.  
  149. static int
  150. sf_write_header(pcap_dumper_t *p, int linktype, int thiszone, int snaplen)
  151. {
  152.     FILE *fp = p->wfile;
  153.     struct pcap_file_header hdr;
  154.     struct pcap_file_snoop_header snoop;
  155.  
  156.     switch (p->format) {
  157.     case FORMAT_TCPDUMP:
  158.         hdr.magic = TCPDUMP_MAGIC;
  159.         hdr.version_major = PCAP_VERSION_MAJOR;
  160.         hdr.version_minor = PCAP_VERSION_MINOR;
  161.  
  162.         hdr.thiszone = thiszone;
  163.         hdr.snaplen = snaplen;
  164.         hdr.sigfigs = 0;
  165.         hdr.linktype = linktype;
  166.  
  167.         if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
  168.             return -1;
  169.  
  170.         break;
  171.     case FORMAT_SNOOP2:
  172.         memcpy(snoop.id, SNOOP_MAGIC, sizeof(snoop.id));
  173.         snoop.version = 2;
  174.         snoop.linktype = link_type[linktype];
  175.         if (p->swapped)
  176.             swap_snoop(&snoop);
  177.  
  178.         if (fwrite((char *)&snoop, sizeof(snoop), 1, fp) != 1)
  179.             return -1;
  180.  
  181.         break;
  182.     }
  183.  
  184.     return 0;
  185. }
  186.